home *** CD-ROM | disk | FTP | other *** search
/ APDL Other Worlds / APDL Other Worlds Collection.iso / SF3000 / Extras / !SFtoSpr / c / SaveMapTiles < prev    next >
Encoding:
Text File  |  2003-11-06  |  11.2 KB  |  318 lines

  1. /*
  2.  *  SFtoSpr - Star Fighter 3000 graphics converter
  3.  *  Savebox for SF3000 MapTiles file
  4.  *  Copyright (C) 2000  Chris Bazley
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public Licence as published by
  8.  *  the Free Software Foundation; either version 2 of the Licence, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public Licence for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public Licence
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. /* ANSI library files */
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdbool.h>
  26.  
  27. /* RISC OS library files */
  28. #include "wimp.h"
  29. #include "toolbox.h"
  30. #include "event.h"
  31. #include "wimplib.h"
  32. #include "saveas.h"
  33. #include "window.h"
  34. #include "gadgets.h"
  35. #include "flex.h"
  36.  
  37. /* My library files */
  38. #include "err.h"
  39. #include "msgtrans.h"
  40. #include "hourglass.h"
  41. #include "FilePerc.h"
  42. #include "ViewsMenu.h"
  43. #include "Macros.h"
  44. #include "TboxBugs.h"
  45.  
  46. /* Local headers */
  47. #include "SFformats.h"
  48. #include "SprFormats.h"
  49. #include "Utils.h"
  50. #include "Loader.h"
  51. #include "Main.h"
  52. #include "SaveMapTiles.h"
  53.  
  54. /* Gadget IDs */
  55. #define SPRTOTEX_SP1        0x0c
  56. #define SPRTOTEX_SP2        0x10
  57. #define SPRTOTEX_TR         0x00
  58. #define SPRTOTEX_TRB        0x100
  59. #define SPRTOTEX_MAXNUM     0x116
  60.  
  61. typedef struct _SaveMapTilesData
  62. {
  63.   ObjectId           saveas_id;
  64.   ObjectId           window_id;
  65.   char              *reset_file_name;
  66.   SF_MapTilesSetHdr *tiles_data; /* flex block */
  67. } SaveMapTilesData;
  68.  
  69. /* -----------------------------------------------------------------------
  70.  *                       Function prototypes
  71.  */
  72.  
  73. static ToolboxEventHandler _SaveMapTiles_bumphandler, _SaveMapTiles_savehandler, _SaveMapTiles_buttonshandler, _SaveMapTiles_deletedhandler;
  74. static LoaderFinishedHandler _SaveMapTiles_animsloaded;
  75. static _kernel_oserror *_SaveMapTiles_read_anims(ObjectId win, SF_MapTilesSetHdr **hdr);
  76. static _kernel_oserror *_SaveMapTiles_write_anims(ObjectId win, SF_MapTilesSetHdr **hdr);
  77.  
  78. /* -----------------------------------------------------------------------
  79.  *                         Public functions
  80.  */
  81.  
  82. ObjectId SaveMapTiles_create(char *savepath, int data_saved, SF_MapTilesSetHdr **tiles_data)
  83. {
  84.   /* Must either RE-ANCHOR tiles_data or flex_free() it
  85.      (will only be flex_free'd if we return NULL_ObjectId) */
  86.   SaveMapTilesData *newblk;
  87.   char *views_path;
  88.  
  89.   /* Grab memory */
  90.   newblk = malloc(sizeof(SaveMapTilesData));
  91.   if(newblk == NULL)
  92.     MG_RETV("NoMem", NULL_ObjectId) /* failure */
  93.  
  94.   newblk->reset_file_name = NULL;
  95.  
  96.   /* Create object */
  97.   if(E(toolbox_create_object(0, "SprToTex", &newblk->saveas_id)))
  98.     goto errexit_free;
  99.   if(E(saveas_get_window_id(0, newblk->saveas_id, &newblk->window_id)))
  100.     goto errexit_delete;
  101.  
  102.   /* Store default settings */
  103.   if((newblk->reset_file_name = copystring(savepath)) == NULL)
  104.     goto errexit_delete;
  105.  
  106.   /* Add entry to iconbar menu */
  107.   if(data_saved)
  108.     views_path = savepath; /* we have real filepath */
  109.   else
  110.     views_path = ""; /* dummy filepath */
  111.   if(E(ViewsMenu_add(newblk->saveas_id, msgs_lookup_sub1("SprTexList", tail(savepath, 3)), views_path)))
  112.     goto errexit_delete;
  113.  
  114.   /* Set up window */
  115.   if(E(saveas_set_file_name(0, newblk->saveas_id, savepath))
  116.   || E(saveas_set_file_type(0, newblk->saveas_id, FILETYPE_MAPTILES))
  117.   || E(saveas_set_file_size(0, newblk->saveas_id, flex_size((flex_ptr)tiles_data)))
  118.   || E(numberrange_set_value(0, newblk->window_id, SPRTOTEX_MAXNUM, (*tiles_data)->lasttile_num))
  119.   || E(_SaveMapTiles_write_anims(newblk->window_id, tiles_data)))
  120.     goto errexit_menuremove;
  121.  
  122.   if(E(loader_register_listener(0, FILETYPE_TEXT, newblk->window_id, NULL, load_animations, _SaveMapTiles_animsloaded, newblk)))
  123.     goto errexit_menuremove;
  124.  
  125.   /*
  126.      Note the ObjectDeleted handler is registered AFTER anything that could cause an error and therefore premature deletion!
  127.   */
  128.   if(E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveToFile,  _SaveMapTiles_savehandler, newblk))
  129.   || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_DialogueCompleted, delete_object_handler, newblk))
  130.   || E(event_register_toolbox_handler(newblk->window_id, ActionButton_Selected, _SaveMapTiles_buttonshandler, newblk))
  131.   || E(event_register_toolbox_handler(newblk->window_id, NumberRange_ValueChanged,  _SaveMapTiles_bumphandler, newblk))
  132.   || E(event_register_toolbox_handler(newblk->saveas_id, Toolbox_ObjectDeleted,  _SaveMapTiles_deletedhandler, newblk)))
  133.     goto errexit_menuremove;
  134.  
  135.   flex_reanchor((flex_ptr)&newblk->tiles_data, (flex_ptr)tiles_data);
  136.   return newblk->saveas_id; /* success */
  137.  
  138.   errexit_menuremove:
  139.     RE(ViewsMenu_remove(newblk->saveas_id));
  140.   errexit_delete:
  141.     RE(toolbox_delete_object(0, newblk->saveas_id));
  142.   errexit_free:
  143.     free(newblk->reset_file_name);
  144.     free(newblk);
  145.     return NULL_ObjectId; /* failure */
  146. }
  147.  
  148. /* -----------------------------------------------------------------------
  149.  *                          Private functions
  150.  */
  151.  
  152. static _kernel_oserror *_SaveMapTiles_read_anims(ObjectId win, SF_MapTilesSetHdr **hdr)
  153. {
  154.   for(int byte = 0; byte < 4; byte++) {
  155.     int value;
  156.     THROW(numberrange_get_value(0, win, SPRTOTEX_SP1 + byte, &value));
  157.     (*hdr)->splash_anim_1[byte] = (char)value;
  158.     THROW(numberrange_get_value(0, win, SPRTOTEX_SP2 + byte, &value));
  159.     (*hdr)->splash_anim_2[byte] = (char)value;
  160.     THROW(numberrange_get_value(0, win, SPRTOTEX_TR + byte, &value));
  161.     (*hdr)->splash_2_triggers[byte] = (char)value;
  162.   }
  163.   return NULL; /* success */
  164. }
  165.  
  166. /* ----------------------------------------------------------------------- */
  167.  
  168. static _kernel_oserror *_SaveMapTiles_write_anims(ObjectId win, SF_MapTilesSetHdr **hdr)
  169. {
  170.   for(int byte = 0; byte < 4; byte++) {
  171.     int temp;
  172.     THROW(numberrange_set_value(0, win, SPRTOTEX_SP1 + byte, (*hdr)->splash_anim_1[byte]));
  173.     THROW(numberrange_set_value(0, win, SPRTOTEX_SP2 + byte, (*hdr)->splash_anim_2[byte]));
  174.     temp = (*hdr)->splash_2_triggers[byte];
  175.     THROW(numberrange_set_value(0, win, SPRTOTEX_TR + byte, temp));
  176.     THROW(numberrange_set_value(0, win, SPRTOTEX_TRB + byte, temp + 1));
  177.   }
  178.   return NULL; /* success */
  179. }
  180.  
  181. /*
  182.  * Toolbox event handlers
  183.  */
  184.  
  185. static int _SaveMapTiles_bumphandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  186. {
  187.   /* NumberRange clicked on underlying window */
  188.   NumberRangeValueChangedEvent *nrvce = (NumberRangeValueChangedEvent *)event;
  189.  
  190.   if(id_block->self_component < SPRTOTEX_TR
  191.   || id_block->self_component > (SPRTOTEX_TR+3))
  192.     return 0; /* bugger off if not 2nd splash triggers */
  193.  
  194.   /* Synchronise the second displayed number of this trigger pair */
  195.   RE(numberrange_set_value(0, id_block->self_id, SPRTOTEX_TRB + (id_block->self_component - SPRTOTEX_TR), nrvce->new_value + 1));
  196.  
  197.   return 1; /* claim event */
  198. }
  199.  
  200. /* ----------------------------------------------------------------------- */
  201.  
  202. static int _SaveMapTiles_buttonshandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  203. {
  204.   /* ActionButton clicked on underlying window */
  205.   ActionButtonSelectedEvent *abse = (ActionButtonSelectedEvent *)event;
  206.   SaveMapTilesData *blk = (SaveMapTilesData *)handle;
  207.  
  208.   if(!FLAG_SET(abse->hdr.flags, ActionButton_Selected_Adjust))
  209.     return 0; /* not interested */
  210.   
  211.   switch(id_block->self_component) {
  212.     case 0x82bc02: /* Cancel button */
  213.       /* Reset dbox state */
  214.       if(blk->reset_file_name != NULL)
  215.         RE(saveas_set_file_name(0, blk->saveas_id, blk->reset_file_name));
  216.     
  217.       RE(_SaveMapTiles_write_anims(id_block->self_id, &blk->tiles_data));
  218.       break;
  219.       
  220. #ifndef SAVEAS_CRAP /* no point saving state if dbox closes anyway */
  221.     case 0x82bc03: /* Save button */
  222.       /* Additional dbox state saving (animations data is read on save) */
  223.       if(blk->animations != NULL)
  224.         RE(optionbutton_get_state(0, id_block->self_id, TEXTOSPR_SAVEANIMS, &blk->reset_save_anims));
  225.  
  226.       int len;
  227.       E_RETV(saveas_get_file_name(0, blk->saveas_id, NULL, 0, &len), 1)
  228.       free(blk->reset_file_name);
  229.       blk->reset_file_name = malloc(len+1);
  230.       if(blk->reset_file_name == NULL)
  231.         err_complain(255, msgs_global("NoMem"));
  232.       else
  233.         RE(saveas_get_file_name(0, blk->saveas_id, blk->reset_file_name, len, NULL));
  234.       break;
  235. #endif
  236.  
  237.     default:
  238.       return 0; /* unknown component */
  239.   }
  240.  
  241.   return 1; /* claim event */
  242. }
  243.  
  244. /* ----------------------------------------------------------------------- */
  245.  
  246. static int _SaveMapTiles_savehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  247. {
  248.   SaveAsSaveToFileEvent *save_to_file_block = (SaveAsSaveToFileEvent *)event;
  249.   SaveMapTilesData *blk = (SaveMapTilesData *)handle;
  250.   unsigned int flags = 0;
  251.  
  252.   /* Read displayed animations data into header
  253.   N.B. This has the desired side effect of confirming the displayed
  254.   animations for use if the dbox is reset (e.g. ADJUST-click 'Cancel') */
  255.   if(E(_SaveMapTiles_read_anims(blk->window_id, &blk->tiles_data)))
  256.     goto exit;
  257.  
  258.   /* Check animations */
  259.   if(!check_animations(&blk->tiles_data))
  260.     goto exit;
  261.  
  262.   /* Save to compressed Fednet file */
  263.   {
  264.     _kernel_oserror *err = perc_operation(FILEPERC_OP_COMP, save_to_file_block->filename, FILETYPE_MAPTILES, (flex_ptr)&blk->tiles_data);
  265.     if(err != NULL)
  266.       err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
  267.     else
  268.       flags = 1; /* success */
  269.   }
  270.  
  271. exit:
  272.   saveas_file_save_completed(flags, id_block->self_id, save_to_file_block->filename);
  273.   return 1; /* claim event */
  274. }
  275.  
  276. /* ----------------------------------------------------------------------- */
  277.  
  278. static int _SaveMapTiles_deletedhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
  279. {
  280.   SaveMapTilesData *blk = (SaveMapTilesData *)handle;
  281.  
  282.   /* Deregister handlers */
  283.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveToFile, _SaveMapTiles_savehandler, handle));
  284.   RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_DialogueCompleted, delete_object_handler, handle));
  285.   RE(event_deregister_toolbox_handler(blk->window_id, ActionButton_Selected, _SaveMapTiles_buttonshandler, handle));
  286.   RE(event_deregister_toolbox_handler(blk->window_id, NumberRange_ValueChanged,  _SaveMapTiles_bumphandler, handle));
  287.   RE(event_deregister_toolbox_handler(id_block->self_id, Toolbox_ObjectDeleted, _SaveMapTiles_deletedhandler, handle));
  288.  
  289.   RE(loader_deregister_listener(FILETYPE_TEXT, blk->window_id, NULL));
  290.  
  291.   /* Remove from iconbar menu */
  292.   RE(ViewsMenu_remove(id_block->self_id));
  293.  
  294.   /* free memory */
  295.   flex_free((flex_ptr)&blk->tiles_data);
  296.   free(blk->reset_file_name);
  297.   free(blk);
  298.  
  299.   if(last_savebox == id_block->self_id)
  300.     last_savebox = NULL_ObjectId;
  301.  
  302.   return 1; /* claim event */
  303. }
  304.  
  305. /*
  306.  * Loader handlers
  307.  */
  308.  
  309. static void _SaveMapTiles_animsloaded(char *title, bool data_saved, flex_ptr buffer, int filetype, void *handle)
  310. {
  311.   /* Fill textfields with animations data */
  312.   SaveMapTilesData *blk = (SaveMapTilesData *)handle;
  313.  
  314.   RE(_SaveMapTiles_write_anims(blk->window_id, (SF_MapTilesSetHdr **)buffer));
  315.  
  316.   flex_free(buffer);
  317. }
  318.